home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / comm / tcp / NameServer.lha / nameserver / named.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-05  |  9.5 KB  |  234 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <netdb.h>
  5. #include <sys/types.h>
  6. #include <sys/syslog.h>
  7. #include <sys/socket.h>
  8. #include <sys/errno.h>
  9. #include <netinet/in.h>
  10. #include <arpa/nameser.h>
  11.  
  12. #include <exec/nodes.h>
  13. #include <exec/lists.h>
  14.  
  15. // Protos
  16. #include <proto/exec.h>
  17. #include <proto/miami.h>
  18. #include <proto/socket.h>
  19. int dn_expand(char *msg, char *eomorig, char *comp_dn, char *exp_dn, int length);
  20. u_char dn_comp(char *exp_dn, char *comp_dn, int length, char **dnptrs, char **lastdnptr);
  21.  
  22. #include "rev.h"
  23. char version[] = "\0$VER: " PROGNAME PROGVERSION " " __AMIGADATE__;
  24.  
  25. struct hostinfo {
  26.         struct MinNode Node;
  27.         char name[MAXDNAME];
  28.         LONG netnumber;
  29. };
  30. struct MinList hostlist;
  31. char Line[1024];
  32. char hostname[MAXHOSTNAMELEN];
  33. char *curnet="";
  34.  
  35.  
  36. void send_err(int s,char *msg,int msglen,struct sockaddr_in *to,LONG tolen,short rcode)
  37. {
  38.         HEADER *h;
  39.         
  40.         h=(HEADER *)msg+sizeof(HEADER);
  41.         h->qr=1;
  42.         h->rcode=rcode;
  43.         sendto(s,msg,msglen,0,(struct sockaddr *)to,tolen);
  44.         
  45. #ifdef DEBUG
  46.         switch(rcode)
  47.         {
  48.                 case FORMERR:   puts("FORMERR send");break;
  49.                 case SERVFAIL:  puts("FORMFAIL send");break;
  50.                 case NXDOMAIN:  puts("NXDOMAIN send");break;
  51.                 default:        puts("UNKNOWN ERROR send");break;
  52.         }
  53. #endif
  54. }
  55.  
  56. main()
  57. {
  58.         struct servent *sp;
  59.         struct sockaddr_in sin;
  60.         struct sockaddr_in from;
  61.         struct hostinfo *hp,*hi;
  62.         struct hostent *host;
  63.         LONG fromlen;
  64.         char msg[PACKETSZ];
  65.         char *lmsg;
  66.         char dnbuf[MAXDNAME];
  67.         char *cp,*eom;
  68.         int msglen;
  69.         int s,n;
  70.         short type,class;
  71.         
  72.         sp=getservbyname("domain","udp");
  73.         if(!sp)
  74.         {
  75.                 fprintf(stderr,"nameserver: tcp/nameserver: unknown service\n");
  76.                 exit(1);
  77.         }
  78.         
  79.         s=socket(AF_INET,SOCK_DGRAM,0);
  80.         if(s==-1)
  81.         {
  82.                 perror("nameserver: create socket");
  83.                 exit(1);
  84.         }
  85.         
  86.         bzero(&sin,sizeof(sin));
  87.         sin.sin_port=sp->s_port;
  88.  
  89.         if(bind(s,(struct sockaddr *)&sin,sizeof(sin))==-1)
  90.         {
  91.                 perror("nameserver: bind");
  92.                 exit(1);
  93.         }
  94.         
  95.         if(gethostname(hostname,sizeof(hostname))==-1)
  96.         {
  97.                 perror("nameserver: gethostname");
  98.                 exit(1);
  99.         }
  100.         if(cp=strchr(hostname,'.')) curnet=cp;
  101.         
  102.         NewList((struct List *)&hostlist);
  103.         
  104. #ifdef DEBUG
  105.         printf("nameserver started\n");
  106. #endif
  107.         for(;;)
  108.         {
  109.                 fromlen=sizeof(from);
  110.                 if((msglen=recvfrom(s,msg,sizeof(msg),0,(struct sockaddr *)&from,&fromlen))==-1)
  111.                 {
  112.                         perror("nameserver: recvfrom");
  113.                 }
  114.                 else
  115.                 {
  116.                         HEADER *h;
  117.                         h=(HEADER *)msg;
  118.                         cp=msg+sizeof(HEADER);
  119.                         eom=msg+msglen;
  120. #ifdef DEBUG
  121.                         printf( "datagram received:\n"
  122.                                                 "  from   : %s\n"
  123.                                                 "  opcode : %d\n"
  124.                                                 "  qdqount: %d\n"
  125.                                                 ,inet_ntoa(from.sin_addr)
  126.                                                 ,h->opcode
  127.                                                 ,h->qdcount
  128.                         );
  129. #endif
  130.                         switch(h->opcode)
  131.                         {
  132.                                 case QUERY:
  133.                                         if(h->qdcount!=1 || h->ancount || h->nscount || h->arcount)
  134.                                         {
  135.                                                 h->qdcount=0;
  136.                                                 h->ancount=0;
  137.                                                 h->nscount=0;
  138.                                                 h->arcount=0;
  139.                                                 send_err(s,msg,msglen,&from,fromlen,FORMERR);
  140.                                                 continue;
  141.                                         }
  142.                                         if((n=dn_expand(msg,eom,cp,dnbuf,sizeof(dnbuf)))<0)
  143.                                         {
  144.                                                 send_err(s,msg,msglen,&from,fromlen,FORMERR);
  145.                                                 continue;
  146.                                         }
  147.                                         cp+=n;
  148.                                         GETSHORT(type, cp);
  149.                                         GETSHORT(class, cp);
  150.                                         if(cp>eom)
  151.                                         {
  152.                                                 send_err(s,msg,msglen,&from,fromlen,FORMERR);
  153.                                                 continue;
  154.                                         }
  155. #ifdef DEBUG
  156.                                         printf("  host   : %s\n",dnbuf);
  157.                                         printf("  type   : %d\n",type);
  158.                                         printf("  class  : %d\n",class);
  159. #endif
  160.                                         if(type!=T_A || class!=C_IN)
  161.                                         {
  162.                                                 send_err(s,msg,msglen,&from,fromlen,NOTIMP);
  163.                                                 continue;
  164.                                         }
  165.                                         
  166.                                         // search host in cache list
  167.                                         hp=NULL;
  168.                                         for(hi=(struct hostinfo *)hostlist.mlh_Head;hi!=(struct hostinfo *)&hostlist.mlh_Tail;hi=(struct hostinfo *)hi->Node.mln_Succ)
  169.                                         {
  170.                                                 if(!strcmp(hi->name,dnbuf))
  171.                                                 {
  172.                                                         hp=hi;
  173.                                                         break;
  174.                                                 }
  175.                                         }       
  176.  
  177.                                         if(!hp) // not found
  178.                                         {
  179.                                                 if( !(host = gethostbyname( dnbuf ) ) )
  180.                                                 {
  181.                                                         send_err(s,msg,msglen,&from,fromlen,NXDOMAIN);
  182.                                                         continue;
  183.                                                 }
  184.                                                 else
  185.                                                 {
  186.                                                         struct hostinfo *newhi;
  187.                         
  188.                                                         if(newhi=malloc(sizeof(struct hostinfo)))
  189.                                                         {
  190.                                                                 strcpy(newhi->name,dnbuf);
  191.                                                                 memcpy( &newhi->netnumber, &host->h_addr_list[ 0 ][ 0 ], 4 );
  192. #ifdef DEBUG
  193.                                                                 printf("add '%s' to cache\n",newhi->name);
  194. #endif
  195.                                                                 AddTail((struct List *)&hostlist,(struct Node *)newhi);
  196.                                                                 hi = newhi;
  197.                                                         }
  198.                                                 }
  199.                                         }
  200.                                         
  201.                                         lmsg=msg+sizeof(msg);
  202.                                         if((n=dn_comp(dnbuf,cp,lmsg-cp,NULL,NULL))<0)
  203.                                         {
  204.                                                 send_err(s,msg,msglen,&from,fromlen,SERVFAIL);
  205.                                                 continue;                                               
  206.                                         }
  207.                                         cp+=n;
  208.                                         if(cp+14>lmsg)
  209.                                         {
  210.                                                 send_err(s,msg,msglen,&from,fromlen,SERVFAIL);
  211.                                                 continue;                       
  212.                                         }
  213.                                         
  214.                                         PUTSHORT(type, cp);
  215.                                         PUTSHORT(class, cp);
  216.                                         PUTLONG(100000,cp);
  217.                                         PUTSHORT(sizeof(LONG),cp);
  218.                                         PUTLONG(hi->netnumber,cp);
  219.                                         
  220.                                         h->qr=1;
  221.                                         h->rcode=NOERROR;
  222.                                         h->ancount=1;
  223.                                         sendto(s,msg,cp-msg,0,(struct sockaddr *)&from,fromlen);
  224. #ifdef DEBUG
  225.                                         printf("answer: %s(%s) send\n",dnbuf,Inet_NtoA(hi->netnumber));
  226. #endif
  227.                                         break;
  228.                                 default:
  229.                                         send_err(s,msg,msglen,&from,fromlen,NOTIMP);
  230.                         }
  231.                 }
  232.         }
  233. }
  234.